<?php 
/**
 * @package base
 */
require_once "_dbobject.php";
require_once "_sitecontext.php";
require_once "_constants.php";
require_once "_htmloffer.php";
require_once "_error.php";
require_once "_codemanager.php";

/**
 * Class that provides search framework for EAIIS application.
 *
 */
class Search {
	const querySpecInitial = "AND (";
	
	private function __construct() {
	
	}
	private static $columns = array("town", "street", "title", "text");
	
	/**
	 * Query specification
	 * Safely specify set of targets in which to look for.
	 * 
	 * @return string - additional specification in format ' AND (...smth1...) AND (...smth2...)'
	 */
	private static function querySpecification() {
		$cm = CodeManager::getCodeManager();
		if (@isset($_REQUEST[Constants::SEARCH_RENTORSALE])) {
			if ($_REQUEST[Constants::SEARCH_RENTORSALE] == Constants::SEARCH_RENTORSALE_RENT) {
				$querySpec = "AND rentOrSale = 'rent'";
			} else {
				$querySpec = "AND rentOrSale = 'sale'";
			}
		} else {
			$querySpec = "";
		}
		
		/**
		 * Locality specification
		 * query specification should look like
		 *		where ((.. fulltext part ..) AND (query spec11 OR query spec12) AND (query spec21))
		 */
		$querySpecLocality = self::querySpecInitial;
		foreach (Definitions::$SETUP_LOCALITIES as $localityId => $localityName) {
			if (isset($_REQUEST[$localityId])) {
				if ($querySpecLocality == self::querySpecInitial) {
					$querySpecLocality .= "locality = '$localityId'";
				} else {
					$querySpecLocality .= " OR locality = '$localityId'";
				}
			}
		}
		/** Add this to query specification variable */
		if ($querySpecLocality != self::querySpecInitial) {
			$querySpec .= $querySpecLocality . ")";
		}
		/** Price specification */
		$querySpecPrice = self::querySpecInitial;
		
		$priceBottom = intval(@$_REQUEST[Constants::SEARCH_PRICEBOTTOM]);
		$priceTop = intval(@$_REQUEST[Constants::SEARCH_PRICETOP]);
		if ($priceBottom > 0) {
			$querySpecPrice .= "price > $priceBottom";
		}
		if ($priceTop > 0) {
			if ($querySpecPrice == self::querySpecInitial) {
					$querySpecPrice .= "price < $priceTop";
			} else {
				$querySpecPrice .= " AND price < $priceTop";
			}
		}
		if ($priceBottom > $priceTop && $priceTop > 0) {
			Error::getError()->addNoticeMessage($cm->get("30200"));
		}
		
		/** Add this to query specification variable */
		if ($querySpecPrice != self::querySpecInitial) {
			$querySpec .= $querySpecPrice . ")";
		}
		
		/** Area specification */
		$querySpecArea = self::querySpecInitial;
		
		$areaBottom = intval(@$_REQUEST[Constants::SEARCH_AREABOTTOM]);
		$areaTop = intval(@$_REQUEST[Constants::SEARCH_AREATOP]);
		if ($areaBottom > 0) {
			$querySpecArea .= "size > $areaBottom";
		}
		if ($areaTop > 0) {
			if ($querySpecArea == self::querySpecInitial) {
					$querySpecArea .= "size < $areaTop";
			} else {
				$querySpecArea .= " AND size < $areaTop";
			}
		}
		if ($areaBottom > $areaTop && $areaTop > 0) {
			Error::getError()->addNoticeMessage($cm->get("30201"));
		}
		
		/** Add this to query specification variable */
		if ($querySpecArea != self::querySpecInitial) {
			$querySpec .= $querySpecArea . ")";
		}
		
		return $querySpec;
	}
	
	public static function init() {
		
		$info = SiteContext::getSiteContext();
		$dbConnector = $info->getDBConnector();
		
		$lang = $info->getSiteLang()->getLang();
		
		if (@!isset($_REQUEST[Constants::SEARCH_FULLTEXT])) {
			$searchSafe = "";
		} else {
			$searchSafe = mysql_real_escape_string(@$_REQUEST[Constants::SEARCH_FULLTEXT], DBConnectorMySQL::getInitialResource());
		}
		/*
		 * EXAMPLE OF AN QUERY
		 * "select * from offers 
		 * 		join (codeslong as c0, codeslong as c1)
		 * 		on (offers.title=c1.id AND offers.text=c2.id)
		 * 		where (offers.town rlike 'rado' or c0.en rlike 'rado')"
		 */ 
		/** for every column from offers which needs to be resolved from codes do join */
		$joinQuery = " join (";
		/** join "on" statement - which table columns should meet certain conditions */
		$onQuery = ") on (";
		/** where statement - added at the end */
		$whereQuery = ") where ((";
		/** used for aliases of codes table */
		$iteratorCodes = 0;
		
		foreach (self::$columns as $column) {
			if ($whereQuery != ") where ((") {
				/** in second and following case, add OR */
				$whereQuery .=" OR ";
			}
			if (@Offer::$CODES_COLUMNS_ASSOC[$column]) {
				/** codes should be resolved */
				if ($iteratorCodes == 0) {
					$joinQuery .= "codeslong as c$iteratorCodes";
					$onQuery .= "offers.".$column."=c$iteratorCodes.id";
				} else {
					$joinQuery .= ", codeslong as c$iteratorCodes";
					$onQuery .= " and offers.".$column."=c$iteratorCodes.id";
				}
				$whereQuery .= "c$iteratorCodes.$lang rlike '$searchSafe'";
				++$iteratorCodes;
			} else {
				/** current column isn't in join statement */
				/** so just add rlike match */
				$whereQuery .= "offers.$column rlike '$searchSafe'";
			}
		}
		
		if (Policy::isAdminView()) {
			$whereQueryEnd = " )";
		} else {
			$whereQueryEnd = " AND status = 'visible')";
		}
		
		$searchQuerySpec = self::querySpecification();
		
		if ($searchSafe != "") {
			$searchQuery = $joinQuery.$onQuery.$whereQuery.")".$searchQuerySpec.$whereQueryEnd;
		} else {
			if ($searchQuerySpec == "") {
				if (Policy::isAdminView()) {
					$searchQuery = "";
				} else {
					$searchQuery = " where ( status = 'visible')";
				}
			} else {
				$searchQuerySpec = preg_replace("/^AND/", "", $searchQuerySpec);
				$searchQuery = " where ( ".$searchQuerySpec.$whereQueryEnd;
			}
			
		}
		
		/** Display search results */
		HtmlOfferBase::pickHtmlOfferInitializer($searchQuery);		
	}
}
?>